package org.ccay.core.xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException;

import org.ccay.core.log.ILogger;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.util.EncodingUtil;
import org.ccay.core.util.exception.FileProcessException;

/**
 * 大型xml文件写入文件工具类，提供一组写入元素节点的方法
 * Created：2013-8-5
 * @author chaowangbang
 * @version:
 */
public class BigXmlWriteHandler {
	
	private static final String format = EncodingUtil.UTF_8; // 文档的编码格式声明
	private XMLWriter xmlWrite; // 写出流
	private static final ILogger log = CcayLoggerFactory.getLogger(BigXmlWriteHandler.class);
	private static final String XML_WRITER = "ccay.core.00060003";
	

	/**
	 * 构造方法
	 * @param filePath
	 * @param format
	 */
	public BigXmlWriteHandler(String filePath) {
		this.xmlWrite = createWrite(filePath);
	}
	
	/**
	 * 构造方法
	 * @param filePath
	 * @param format
	 */
	public BigXmlWriteHandler(OutputStream outputStream) {
		OutputFormat outputFormat = OutputFormat.createPrettyPrint();
		outputFormat.setEncoding(format);
		try {
			this.xmlWrite = new XMLWriter(outputStream, outputFormat);
		} catch (UnsupportedEncodingException e) {
			log.error(e);
			throw new FileProcessException(XML_WRITER, e);
		}
	}

	protected XMLWriter createWrite(String filePath) {
		XMLWriter write = null;
		try {
			OutputFormat outputFormat = OutputFormat.createPrettyPrint();
			outputFormat.setEncoding(format);
			write = new XMLWriter(new FileOutputStream(filePath), outputFormat);
		} catch (UnsupportedEncodingException e) {
			log.error(e);
			throw new FileProcessException(XML_WRITER, e);
		} catch (FileNotFoundException e) {
			log.error(e);
			throw new FileProcessException(XML_WRITER, e);
		}
		return write;
	}

	/**
	 * 关闭写出流
	 */
	public void close() {
		if(xmlWrite != null) {
			try {
				xmlWrite.flush();
				xmlWrite.close();
			} catch (IOException ioe) {
				log.error("Could not close " + this.xmlWrite, ioe);
			}
		}
	}

	/**
	 * 打开文档
	 * @throws SAXException 
	 */
	public void startDocument() throws SAXException {
		try {
			xmlWrite.startDocument();
		} catch (SAXException e) {
			log.error(e);
			throw e;
		}
	}

	/**
	 * 关闭文档
	 * @throws SAXException 
	 */
	public void endDocument() throws SAXException {
		try {
			xmlWrite.endDocument();
		} catch (SAXException e) {
			log.error(e);
			throw e;
		}
	}

	/**
	 * 写入一个元素节点,包括开始和结束标签
	 * @param element
	 * @throws IOException 
	 */
	public void write(Element element) throws IOException {
		try {
			xmlWrite.write(element);
		} catch (IOException e) {
			log.error(e);
			throw e;
		}
	}

	/**
	 * 写入元素关闭标签
	 * @param element
	 * @throws IOException 
	 */
	public void writeClose(Element element) throws IOException {
		try {
			xmlWrite.writeClose(element);
		} catch (IOException e) {
			log.error(e);
			throw e;
		}
	}

	/**
	 * 写入元素开始标签
	 * @param element
	 * @throws IOException 
	 */
	public void writeOpen(Element element) throws IOException {
		try {
			xmlWrite.writeOpen(element);
		} catch (IOException e) {
			log.error(e);
			throw e;
		}
	}
}

